package com.ktjiaoyu.crm.service;

import com.ktjiaoyu.crm.pojo.Right;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service("shiroService")
public class ShiroServiceImpl implements ShiroService {

    @Autowired
    private RightService rightService;

    /**
     * 动态加载初始权限
     * @return
     */
    @Override
    public Map<String, String> loadFilterChainDefinitions() {
        log.info("shiro动态加载初始权限.........");
        //用LinkedHashMap添加拦截的uri,其中authc指定需要认证的uri，anon指定排除认证的uri
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //配置可以匿名访问的资源：静态资源
        //anon:所有url都都可以匿名访问;
        //authc:需要认证才能进行访问;
        //perms:权限授权拦截，验证用户是否拥有指定权限;
        //user:配置记住我或认证通过可以访问；
        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/fonts/**","anon");
        filterChainDefinitionMap.put("/images/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/localcss/**","anon");
        filterChainDefinitionMap.put("/localjs/**","anon");
        filterChainDefinitionMap.put("/login","anon");
        filterChainDefinitionMap.put("/main","anon");

        //动态授权：所有权限从数据库中查询
        //遍历权限列表
        List<Right> allRights = rightService.list();
        for (Right right : allRights){
            //此处判断URL不为空是因为父权限URL不需要跳转页面，所以会出现空的情况
            //需要排除父权限URL
            if(right.getRightUrl()!=null && !right.getRightUrl().trim().equals("")){
                filterChainDefinitionMap.put(right.getRightUrl(),"perms["+right.getRightCode()+"]");
            }
        }
        //配置认证访问：其他资源(URL)必须认证通过才能访问
        filterChainDefinitionMap.put("/**","authc"); //必须放在过滤器链的最后面
        return filterChainDefinitionMap;
    }

    /**
     * 刷新初始权限
     */
    @Override
    public void reloadFilterChainDefinitions() {

        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            ServletContext servletContext = request.getSession().getServletContext();
            AbstractShiroFilter shiroFilter = (AbstractShiroFilter) WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext).getBean("shiroFilterFactory");
            synchronized (shiroFilter) {
                // 获取过滤管理器
                PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
                DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
                // 清空初始权限配置
                manager.getFilterChains().clear();
                // 重新加载动态权限，配置权限验证规则
                Map<String, String> chains = loadFilterChainDefinitions();
                // System.out.println("chains-------"+chains);
                for (Map.Entry<String, String> entry : chains.entrySet()) {
                    String url = entry.getKey();
                    String chainDefinition = entry.getValue().trim().replace(" ", " ");
                    manager.createChain(url, chainDefinition);
                }
                log.info("调用reloadFilterChainDefinitions()更新权限成功！！ ");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
